from elasticsearch import Elasticsearch
from rest_framework.views import APIView
from rest_framework.response import Response
from app.models import Godds, Foods, GoodsCategory
from rest_framework import status

# 连接到 Elasticsearch 客户端
es = Elasticsearch("http://118.178.236.180:9200")

# 定义索引名称
goods_with_categories_index = "goods_with_categories"
foods_index = "foods"

# 创建索引（如果不存在）
for index_name, mappings in [
    (goods_with_categories_index, {
        "mappings": {
            "properties": {
                "id": {"type": "integer"},
                "name": {"type": "text"},  # 商品名称
                "sale": {"type": "integer"},  # 销量
                "category_title": {"type": "text"},  # 分类名称
                "pid": {"type": "integer"},  # 分类ID
                "topid": {"type": "integer"}  # 顶级分类ID
            }
        }
    }),
    (foods_index, {
        "mappings": {
            "properties": {
                "id": {"type": "integer"},
                "name": {"type": "text"},  # 食物名称
                "price": {"type": "float"},  # 价格
                "sale": {"type": "integer"}  # 销量
            }
        }
    }),
]:
    if not es.indices.exists(index=index_name):
        es.indices.create(index=index_name, body=mappings)
        print(f"索引 {index_name} 创建成功！")


# 数据同步类视图
class DataSyncView(APIView):
    def get(self, request):
        # 同步 Godds 和 GoodsCategory 数据（合并展示）
        goods_data = Godds.objects.all()
        categories = GoodsCategory.objects.all()
        category_dict = {cat.id: cat.title for cat in categories}  # 构建分类字典

        for item in goods_data:
            es.index(index=goods_with_categories_index, id=item.id, body={
                "id": item.id,
                "name": item.name,
                "sale": item.sale,
                "category_title": category_dict.get(item.pid_id, ""),  # 关联的分类名称
                "pid": item.pid_id,
                "topid": item.topid_id
            })

        # 同步 Foods 数据
        foods_data = Foods.objects.all()
        for item in foods_data:
            es.index(index=foods_index, id=item.id, body={
                "id": item.id,
                "name": item.name,
                "price": float(item.price),
                "sale": item.sale
            })

        return Response({"message": "数据同步到 Elasticsearch 成功！"}, status=status.HTTP_200_OK)


# 搜索视图
# 搜索视图
class MultiTableSearchView(APIView):
    def get(self, request):
        # 获取查询参数
        name_condition = request.GET.get('name', '')  # 名称条件
        goods_min_sale = request.GET.get('goods_min_sale')  # 商品最小销量
        goods_max_sale = request.GET.get('goods_max_sale')  # 商品最大销量
        foods_min_sale = request.GET.get('foods_min_sale')  # 食物最小销量
        foods_max_sale = request.GET.get('foods_max_sale')  # 食物最大销量
        foods_min_price = request.GET.get('foods_min_price')  # 食物最低价格
        foods_max_price = request.GET.get('foods_max_price')  # 食物最高价格
        goods_page = int(request.GET.get('goods_with_categories_page', 1))
        goods_page_size = int(request.GET.get('goods_with_categories_page_size', 10))
        foods_page = int(request.GET.get('foods_page', 1))
        foods_page_size = int(request.GET.get('foods_page_size', 10))

        # 构建查询 DSL
        goods_conditions = []
        foods_conditions = []

        # 商品和分类查询条件
        if name_condition:
            goods_conditions.append({"match": {"name": name_condition}})
        if goods_min_sale or goods_max_sale:
            goods_sale_range = {}
            if goods_min_sale:
                goods_sale_range["gte"] = int(goods_min_sale)
            if goods_max_sale:
                goods_sale_range["lte"] = int(goods_max_sale)
            goods_conditions.append({"range": {"sale": goods_sale_range}})

        # 食物查询条件
        if name_condition:
            foods_conditions.append({"match": {"name": name_condition}})
        if foods_min_sale or foods_max_sale:
            foods_sale_range = {}
            if foods_min_sale:
                foods_sale_range["gte"] = int(foods_min_sale)
            if foods_max_sale:
                foods_sale_range["lte"] = int(foods_max_sale)
            foods_conditions.append({"range": {"sale": foods_sale_range}})
        if foods_min_price or foods_max_price:
            foods_price_range = {}
            if foods_min_price:
                foods_price_range["gte"] = float(foods_min_price)
            if foods_max_price:
                foods_price_range["lte"] = float(foods_max_price)
            foods_conditions.append({"range": {"price": foods_price_range}})

        # 查询所有数据的条件
        goods_query = {"query": {"bool": {"must": goods_conditions}}} if goods_conditions else {"query": {"match_all": {}}}
        foods_query = {"query": {"bool": {"must": foods_conditions}}} if foods_conditions else {"query": {"match_all": {}}}

        # 添加分页
        goods_query['from'] = (goods_page - 1) * goods_page_size
        goods_query["size"] = goods_page_size
        foods_query["from"] = (foods_page - 1) * foods_page_size
        foods_query["size"] = foods_page_size

        results = {}
        try:
            # 查询 Elasticsearch
            goods_response = es.search(index="goods_with_categories", body=goods_query)
            goods_hits = goods_response["hits"]["hits"]
            goods_results = [hit["_source"] for hit in goods_hits]

            foods_response = es.search(index="foods", body=foods_query)
            foods_hits = foods_response["hits"]["hits"]
            foods_results = [hit["_source"] for hit in foods_hits]

            results = {
                "goods_with_categories": goods_results,
                "foods": foods_results
            }

            return Response({
                "total": {
                    "goods_with_categories": goods_response["hits"]["total"]["value"],
                    "foods": foods_response["hits"]["total"]["value"]
                },
                "page": {
                    "goods_with_categories": goods_page,
                    "foods": foods_page
                },
                "page_size": {
                    "goods_with_categories": goods_page_size,
                    "foods": foods_page_size
                },
                "data": results
            }, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

